<?php
// 应用公共文件

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;
use PHPMailer\PHPMailer\PHPMailer;
use TencentCloud\Common\Credential;
use TencentCloud\Sms\V20210111\Models\SendSmsRequest;
use TencentCloud\Sms\V20210111\SmsClient;
use think\facade\Cache;
use think\facade\Db;
use think\response\Json;

const API_SUCCESS = 'success';
const API_FAIL = 'fail';
const API_NEED_LOGIN = '请先登陆';
const API_NO_AUTH = '你没有权限';
const API_DB_ERROR = '数据库内部错误';
const API_DATA_NOT_FOUND = '不存在的记录';
function M($table,$usePrefix=true): Db
{
    return Db::table($usePrefix?env('database.prefix').$table:$table);
}
function pr($code, $msg = API_SUCCESS, $data = null): Json
{
    $return = ['code' => $code];
    if (is_array($msg)) {
        $data = $msg;
        if ($code == 200) $return['msg'] = "成功"; else $return['msg'] = "失败";
    } else $return['msg'] = $msg;
    if ($data != null || is_array($data)) $return['data'] = $data;
    if (!empty($data['_extra'])) {
        $tmp = $data['_extra'];
        unset($return['data']['_extra']);
        foreach ($tmp as $key => $v) {
            $return = array_merge($return, [$key => $v]);
        }
    }
    return json($return);
}

/**
 * hCaptcha 验证
 */
function hCaptcha($response): bool
{
    try {
        $secret = env('hCaptcha_secret');
        $client = new Client(['headers' => ['Content-Type' => 'application/x-www-form-urlencoded']]);
        $response = $client->request('POST', 'https://hcaptcha.com/siteverify', ['form_params' => ['secret' => $secret, 'response' => $response]]);
        return json_decode($response->getBody(), true)['success'];
    } catch (GuzzleException|Exception $e) {
        return false;
    }
}

/**
 * 重要接口防刷
 */
function apiRateLimit($uid, $ip, $area): bool
{
    $info1 = $area['info1'];
    $info2 = $area['info2'];
    $ip_num = Cache::get("ipLimit" . $ip);
    if (empty($ip_num)) {
        Cache::set("ipLimit" . $ip, 1, 24 * 60 * 60);
    }
    $uid_num = Cache::get("uidLimit" . $uid);
    if (empty($uid_num)) {
        Cache::set("uidLimit" . $uid, 1, 24 * 60 * 60);
    }
    $info1_num = Cache::get("areaInfo1Limit" . $info1);
    if (empty($info1_num)) {
        Cache::set("areaInfo1Limit" . $info1, 1, 24 * 60 * 60);
    }
    $info2_num = Cache::get("areaInfo2Limit" . $info2);
    if (empty($info2_num)) {
        Cache::set("areaInfo2Limit" . $info2, 1, 24 * 60 * 60);
    }
    //ip 3次 uid 3次 省/市 200次 市/区 50次  / 每天
    if ($ip_num > 10 || $uid_num > 10 || $info1_num > 10 || $info2_num > 10) {
        return false;
    }
    Cache::inc("ipLimit" . $ip);
    Cache::inc("uidLimit" . $uid);
    Cache::inc("areaInfo1Limit" . $info1);
    Cache::inc("areaInfo2Limit" . $info2);
    return true;
}

/**
 * 通过IP获取地区
 */
function getArea($ip)
{
    try {
        //$url = "http://ip.taobao.com/outGetIpInfo?ip=".$ip."&accessKey=alibaba-inc";
        $url = "https://api.vore.top/api/IPdata?ip=" . $ip;
        $data = Db::table('sc_wardroom_ip')->where(['ip' => $ip])->find();
        if (!empty($u) && $data['time'] < time() - 3600 * 24 * 30) {
            return $data;
        }
        $client = new Client();
        $response = $client->request('GET', $url);
        $result = json_decode($response->getBody(), true);
        if ($result['code'] != 200) {
            return [];
        }
        $type = $result['ipinfo']['type'];
        $info1 = $result['ipdata']['info1'];
        $info2 = $result['ipdata']['info2'];
        $info3 = $result['ipdata']['info3'];
        $isp = $result['ipdata']['isp'];
        $cnip = 0;
        if (str_ends_with($info1, "省") || str_ends_with($info1, "市") || str_ends_with($info1, "区")) {
            $cnip = 1;
        }
        Db::table('sc_wardroom_ip')->insert(['ip' => $ip, 'info1' => $info1, 'info2' => $info2, 'info3' => $info3, $type => $type, 'isp' => $isp, 'cnip' => $cnip, 'time' => time()]);
        return ['info1' => $info1, 'info2' => $info2, 'info3' => $info3, $type => $type, 'isp' => $isp, 'cnip' => $cnip];
    } catch (GuzzleException $e) {
        return [];
    }
}

/**
 * 获取用户IP
 */
function getUserIp()
{
    $real_ip = '';
    if (isset($_SERVER)) {
        if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $real_ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
            $real_ip = $_SERVER['HTTP_CLIENT_IP'];
        } else {
            $real_ip = $_SERVER['REMOTE_ADDR'];
        }
    } else {
        if (getenv('HTTP_X_FORWARDED_FOR')) {
            $real_ip = getenv('HTTP_X_FORWARDED_FOR');
        } else if (getenv('HTTP_CLIENT_IP')) {
            $real_ip = getenv('HTTP_CLIENT_IP');
        } else {
            $real_ip = getenv('REMOTE_ADDR');
        }
    }
    return $real_ip;
}

/**
 * 发送邮件
 */
function SendMail($toEmail, $title, $Content): array
{
    try {
        $mail = new PHPMailer();
        $mail->isSMTP();
        $mail->SMTPAuth = true;
        $mail->Host = env('mail.host');
        $mail->SMTPSecure = 'ssl';
        $mail->Port = 465;
        $mail->CharSet = 'UTF-8';
        $mail->FromName = 'SC中文社区';
        $mail->Username = env('mail.user');
        $mail->Password = env('mail.pass');
        $mail->From = env('mail.from');
        $mail->isHTML(true);
        $mail->Debugoutput = "html";
        $mail->addAddress($toEmail);
        $mail->Subject = $title;
        $mail->Body = $Content;
        //解决ssl证书不信任的问题
        $mail->SMTPOptions = array(
            'ssl' => array(
                'verify_peer' => false,
                'verify_peer_name' => false,
                'allow_self_signed' => true
            )
        );
        $status = $mail->send();
        if (!$status) {
            return ['error' => 1, 'msg' => $mail->ErrorInfo];
        } else {
            return ['error' => 0];
        }
    } catch (Exception $e) {
        return ['error' => 1, 'msg' => $e->getMessage()];
    }
}

/**
 * 发送短信 [通过腾讯云]
 */
function SendSMS($toPhone, $code): array
{
    try {
        $cred = new Credential(env("TencentCloud.SecretId"), env("TencentCloud.SecretKey"));
        $client = new SmsClient($cred, "ap-guangzhou");
        $req = new SendSmsRequest();
        $params = '{"PhoneNumberSet":["+86' . $toPhone . '"],"TemplateID":"100000","Sign":"SC中文社区","TemplateParamSet":["' . $code . '"],"SmsSdkAppid":"1400500000"}';
        $req->fromJsonString($params);
        $resp = $client->SendSms($req);
        return ['error' => 0, 'msg' => $resp->toJsonString()];
    } catch (Exception $e) {
        return ['error' => 1, 'msg' => $e->getMessage()];
    }
}

/**
 * 生成accessToken
 */
function makeAccessToken(): string
{
    return md5(time() . rand(10000, 99999));
}

function getHostUrl($path,$isDownLoad=false): string
{
    $u = 'https://';
    if($isDownLoad){
        $u .= "down.schub.top";
    }else{
        $u .= $_SERVER['HTTP_HOST'];
    }
    if(strpos($path,'./') === 0) $path = substr($path,2,strlen($path)-1);
    if(strpos($path,'/') === 0) $path = substr($path,1,strlen($path)-1);
    $u .= '/' . $path;
    return $u;
}

/**
 * 根据文件长度返回文件大小
 * @param $fsize
 * @return string
 */
function GetFileSize($fsize): string
{
    if ($fsize < 1024) {
        $str = floor($fsize) . " B";
    } elseif ($fsize < 1024 * 1024) {
        $str = round($fsize / 1024, 4) . " KB";
    } elseif ($fsize < 1024 * 1024 * 1024) {
        $str = round($fsize / 1024 / 1024, 4) . " MB";
    } else {
        $str = round($fsize / 1024 / 1024 / 1024, 4) . " GB";
    }
    return $str;
}

/**
 * 获取插件版发过来的AuthCode
 * @return mixed|string
 */
function getAuthCode()
{
    $a = $_SERVER['HTTP_AUTHORIZATION'];
    $b = explode(' ', $a);
    return $b[1];
}

/**
 * 将字节流保存为文件，并返回文件相对路径
 * @param string $fileName 文件名称
 * @param mixed $content
 * @param mixed $uid
 * @param int $start 起始写入位置
 * @return string
 */
function saveToFile(string $fileName, $content, $uid, int $start=0): string
{
    $fileName = md5($fileName);
    if(!empty($uid)) $fileName = md5($fileName.$uid);
    $dir = "./upload/" . date("Y/md/");
    if (!is_dir($dir)) mkdir($dir, 0777, true);
    $p = $dir . $fileName;
    $f = fopen($p, 'cb+');
    fseek($f,$start);
    fwrite($f, $content);
    fclose($f);
    return $p;
}
/**
 * 根据文件后缀返回文档类型
 * @param $fileName
 * @return int
 */
function getSCType($fileName): int
{
    $end = explode('.',$fileName);
    if(count($end)>0){
        $type = $end[count($end)-1];
        switch ($type) {
            case 'scworld':return 1;
            case 'scbtex':return 2;
            case 'scskin':return 3;
            case 'scfpack':return 4;
            case 'scmod':return 5;
            case 'ipa':return 6;
            case 'zip':return 7;
            case '7z':return 8;
            case 'apk':return 9;
            case 'netmod':return 10;
        }
    }
    return 0;
}
/**
 * 根据文档类型返回中文分类名
 * @param $type
 * @return string
 */
function GetScTypeText($type): string
{
    switch($type){
        case 1:return '世界';
        case 2:return '方块材质';
        case 3:return '人物皮肤';
        case 4:return '家具包';
        case 5:return '模组';
        default:return '文件夹';
    }

}
/**
 * 格式化时间戳
 * @param $timestamp
 * @return false|string
 */
function formatTimeStamp($timestamp)
{
    $h = date('H', $timestamp);
    if ($h < 18 && $h >= 12) $state = "下午"; else if ($h >= 0 && $h < 6) $state = "凌晨"; else if ($h >= 6 && $h < 12) $state = "上午"; else if ($h >= 18 && $h < 24) $state = "晚上";
    return date("Y年m月d日 $state H:i", $timestamp);
}

function setLog($txt, $fileName = "testLog.txt")
{
    $myfile = fopen($fileName, "a+") or die("Unable to open file!");
    fwrite($myfile, date('d-m-y h:i:s')."=>".json_encode($txt)."\n");
    fclose($myfile);
}
